import { reactive, ref } from "vue";
import { uploadImage } from "@/utils/unirequest";

// 通用表单数据类型
export type FormDataType = Record<string, any>;

// 选择器事件类型
export interface PickerChangeEvent {
  detail: {
    value: number;
  };
}

// 文件选择事件类型
export interface FileSelectEvent {
  tempFiles: Array<{
    path?: string;
    tempFilePath?: string;
  }>;
}

// 字段配置接口
export interface FieldConfig {
  key: string;
  label: string;
  type: "input" | "textarea" | "picker" | "datetime" | "date" | "native-date" | "image-upload" | "file-upload" | "readonly" | "department-picker" | "autocomplete" | "text";
  placeholder: string;
  required?: boolean;
  inputType?: string;
  maxlength?: number;
  pattern?: string;
  patternErrorMessage?: string;
  options?: string[];
  optionsData?: Array<{ value: string; text: string }>;
  fileConfig?: any;
  readonly?: boolean;
  showInCreate?: boolean;
  showInEdit?: boolean;
  showInDetails?: boolean;
  popupTitle?: string; // 弹窗标题（用于department-picker类型）
  departmentData?: any[]; // 部门数据（用于department-picker类型）
  // 自动补全相关配置
  searchApi?: (query: string) => Promise<Array<{ value: string; text: string }>>;
  minSearchLength?: number;
  debounceTime?: number;
  validation?: (value: any, formData?: any) => { valid: boolean; message: string } | true;
}

// 表单分组接口
export interface FormSection {
  key: string;
  title: string;
  fields: FieldConfig[];
}

// API配置接口
export interface ApiConfig<T = any, K = any> {
  search: (params: any) => Promise<{ Data: T[] }>;
  get: (id: string) => Promise<{ Entity: T }>;
  add: (data: K) => Promise<T>;
  edit: (data: K) => Promise<T>;
  delete: (ids: string[]) => Promise<any>;
  getBillCode?: () => Promise<{ Data: string }>;
}

// 选项数据加载器接口
export interface OptionLoader {
  [key: string]: () => Promise<Array<{ Value: string; Text: string }>>;
}

/**
 * 通用CRUD表单 Composable
 */
export function useCrudForm<TEntity = any, TViewModel = any>(
  formConfig: Record<string, FieldConfig>,
  apiConfig: ApiConfig<TEntity, TViewModel>,
  optionLoaders?: OptionLoader
) {
  // 动态初始化表单数据
  const initFormData = () => {
    const data: FormDataType = {};
    Object.keys(formConfig).forEach(key => {
      const fieldConfig = formConfig[key];
      // 为日期时间字段设置空字符串作为默认值
      if (fieldConfig.type === 'datetime') {
        data[key] = "";
      } else {
        data[key] = "";
      }
    });
    return data;
  };

  // 表单数据
  const formData = reactive<FormDataType>(initFormData());

  // 选择器的实际值（ID）- 用于提交到后端
  const pickerValues = reactive<Record<string, string>>({});

  // 表单错误信息
  const formErrors = reactive<Record<string, string>>({});

  // 加载状态
  const loading = ref(false);

  // 原始数据（用于编辑时保存）
  const originalData = ref<any>(null);

  /**
   * 统一错误处理
   */
  const handleError = (error: any, defaultMessage: string, showToast = true) => {

    if (showToast) {
      const errorMessage =
        error?.response?.data?.Message ||
        error?.message ||
        defaultMessage;

      uni.showToast({
        title: errorMessage,
        icon: "error",
        duration: 2000,
      });
    }
  };

  /**
   * 单个字段校验
   */
  const validateField = (fieldName: string): boolean => {
    const fieldConfig = formConfig[fieldName];
    if (!fieldConfig) return true;

    const value = formData[fieldName];

    // 必填校验
    if (fieldConfig.required && !value) {
      formErrors[fieldName] = `请输入${fieldConfig.label}`;
      return false;
    }

    // 正则校验
    if (fieldConfig.pattern && value) {
      const pattern = new RegExp(fieldConfig.pattern);
      if (!pattern.test(value.toString())) {
        formErrors[fieldName] =
          fieldConfig.patternErrorMessage || `${fieldConfig.label}格式不正确`;
        return false;
      }
    }

    // 自定义校验
    if (fieldConfig.validation && value !== undefined) {
      const result = fieldConfig.validation(value, formData);
      if (result !== true) {
        formErrors[fieldName] = result.message;
        return false;
      }
    }

    // 通过校验，清除错误
    delete formErrors[fieldName];

    return true;
  };

  /**
   * 校验整个表单
   */
  const validateAllFields = (): boolean => {
    let isValid = true;

    // 清空之前的错误信息
    Object.keys(formErrors).forEach((key) => {
      delete formErrors[key];
    });

    // 遍历所有字段进行校验
    Object.keys(formConfig).forEach((fieldKey) => {
      const fieldValid = validateField(fieldKey);
      if (!fieldValid) {
        isValid = false;
      }
    });

    // 如果有错误，显示第一个错误信息
    if (!isValid) {
      const firstError = Object.keys(formErrors)[0];
      if (firstError && formErrors[firstError]) {
        uni.showToast({
          title: formErrors[firstError],
          icon: "none",
          duration: 2000
        });
      }
    }

    return isValid;
  };

  /**
   * 校验整个表单并返回详细的校验结果
   */
  const validateAllFieldsWithDetails = (): { valid: boolean; errors: Record<string, string>; firstErrorMessage?: string } => {
    let isValid = true;

    // 清空之前的错误信息
    Object.keys(formErrors).forEach((key) => {
      delete formErrors[key];
    });

    // 遍历所有字段进行校验
    Object.keys(formConfig).forEach((fieldKey) => {
      const fieldValid = validateField(fieldKey);
      if (!fieldValid) {
        isValid = false;
      }
    });

    // 获取第一个错误信息
    const firstError = Object.keys(formErrors)[0];
    const firstErrorMessage = firstError ? formErrors[firstError] : undefined;

    return {
      valid: isValid,
      errors: { ...formErrors },
      firstErrorMessage
    };
  };

  /**
   * 选择器处理
   */
  const handlePickerChange = (fieldKey: string, e: PickerChangeEvent) => {
    const field = formConfig[fieldKey];
    if (field && field.options) {
      const index = e.detail.value;

      // 如果有选项数据，分别保存显示文本和ID值
      if (field.optionsData && field.optionsData[index]) {
        // 显示文本保存到 formData，用于界面显示
        formData[fieldKey] = field.optionsData[index].text;
        // ID值保存到 pickerValues，用于提交到后端
        pickerValues[fieldKey] = field.optionsData[index].value;
      } else {
        // 兼容没有选项数据的情况
        formData[fieldKey] = field.options[index];
        pickerValues[fieldKey] = field.options[index];
      }

      validateField(fieldKey);
    }
  };

  /**
   * 日期时间处理
   */
  const handleDateTimeChange = (fieldKey: string, value: any) => {
    formData[fieldKey] = value;
    validateField(fieldKey);
  };

  /**
   * 格式化日期时间为 YYYY-MM-DD HH:mm:ss 格式
   */
  const formatDateTime = (dateTimeValue: string | Date | null): string | null => {
    if (!dateTimeValue) return null;

    const date = new Date(dateTimeValue);
    if (isNaN(date.getTime())) return null;

    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    const hours = String(date.getHours()).padStart(2, "0");
    const minutes = String(date.getMinutes()).padStart(2, "0");
    const seconds = String(date.getSeconds()).padStart(2, "0");

    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  };

  /**
   * 身份证照片上传处理
   */
  const handleIdCardPhotoUpload = async (
    fieldKey: "idCardFrontPhoto" | "idCardBackPhoto",
    e: FileSelectEvent
  ): Promise<boolean> => {
    const filePath = e.tempFiles[0].path || e.tempFiles[0].tempFilePath;
    if (!filePath) {
      uni.showToast({
        title: "请选择图片",
        icon: "error",
      });
      return false;
    }

    try {
      uni.showLoading({ title: "上传中..." });
      const imageId = await uploadImage(filePath);
      formData[fieldKey] = imageId;

      uni.hideLoading();
      uni.showToast({
        title: "上传成功",
        icon: "success",
      });

      validateField(fieldKey);
      return true;
    } catch (error) {
      uni.hideLoading();
      handleError(error, `${fieldKey === "idCardFrontPhoto" ? "身份证正面" : "身份证反面"}照片上传失败`);
      return false;
    }
  };

  /**
   * 通用选项数据加载
   */
  const loadOptions = async (fieldKey: string, loader: () => Promise<Array<{ Value: string; Text: string }>>): Promise<boolean> => {
    try {
      const response = await loader();

      if (response && Array.isArray(response)) {
        // 更新表单配置中的选项
        if (formConfig[fieldKey]) {
          formConfig[fieldKey].options = response.map((item: any) => item.Text);
          formConfig[fieldKey].optionsData = response.map((item: any) => ({
            value: item.Value,
            text: item.Text,
          }));
        }
        return true;
      } else {
        handleError(null, `获取${fieldKey}选项数据失败`);
        return false;
      }
    } catch (error) {
      handleError(error, `获取${fieldKey}选项数据失败`);
      return false;
    }
  };

  /**
   * 初始化所有选项数据
   */
  const initializeOptions = async (): Promise<boolean> => {
    if (!optionLoaders) return true;

    const loadPromises = Object.entries(optionLoaders).map(([fieldKey, loader]) =>
      loadOptions(fieldKey, loader)
    );

    const results = await Promise.allSettled(loadPromises);

    // 检查是否所有请求都成功
    const allSuccess = results.every(result =>
      result.status === 'fulfilled' && result.value === true
    );

    if (!allSuccess) {
      // 部分选项数据加载失败
    }

    return allSuccess;
  };

  /**
   * 通用API数据转换为表单数据
   */
  const convertApiDataToFormData = (apiData: TEntity, fieldMapping?: Record<string, string>) => {
    Object.keys(formConfig).forEach(fieldKey => {
      const apiFieldPath = fieldMapping?.[fieldKey] || fieldKey;

      // 处理嵌套属性路径
      const pathParts = apiFieldPath.split(".");
      let value = apiData as any;

      for (const part of pathParts) {
        if (value && typeof value === "object" && part in value) {
          value = value[part];
        } else {
          value = null;
          break;
        }
      }

      const fieldConfig = formConfig[fieldKey];

      // 特殊处理选择器字段
      if (fieldConfig.type === 'picker' && fieldConfig.optionsData) {
        const option = fieldConfig.optionsData?.find(
          (item: any) => item.value === value
        );
        if (option) {
          formData[fieldKey] = option.text;
          pickerValues[fieldKey] = option.value;
        } else {
          formData[fieldKey] = value || "";
          pickerValues[fieldKey] = value || "";
        }
      }
      // 特殊处理日期时间字段
      else if (fieldConfig.type === 'datetime') {
        if (value) {
          // 直接解析字符串，避免时区转换问题
          try {
            // 假设API返回格式为 "YYYY-MM-DD HH:mm:ss" 或 "YYYY-MM-DDTHH:mm:ss"
            const dateStr = value.toString();

            // 提取日期和时间部分
            const match = dateStr.match(/(\d{4})-(\d{2})-(\d{2})[\sT](\d{2}):(\d{2})/);

            if (match) {
              const [, year, month, day, hours, minutes] = match;
              const convertedValue = `${year}-${month}-${day}T${hours}:${minutes}`;
              formData[fieldKey] = convertedValue;
            } else {
              // 如果正则匹配失败，尝试使用Date对象（作为备用方案）
              const date = new Date(value);
              if (!isNaN(date.getTime())) {
                const year = date.getFullYear();
                const month = String(date.getMonth() + 1).padStart(2, '0');
                const day = String(date.getDate()).padStart(2, '0');
                const hours = String(date.getHours()).padStart(2, '0');
                const minutes = String(date.getMinutes()).padStart(2, '0');

                const convertedValue = `${year}-${month}-${day}T${hours}:${minutes}`;
                formData[fieldKey] = convertedValue;
              } else {
                formData[fieldKey] = "";
              }
            }
          } catch (error) {
            formData[fieldKey] = "";
          }
        } else {
          formData[fieldKey] = "";
        }
      }
      // 特殊处理日期字段（只有日期，没有时间）
      else if (fieldConfig.type === 'date') {
        if (value) {
          try {
            // 假设API返回格式为 "YYYY-MM-DD" 或 "YYYY-MM-DD HH:mm:ss"
            const dateStr = value.toString();

            // 提取日期部分
            const match = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);

            if (match) {
              const [, year, month, day] = match;
              const convertedValue = `${year}-${month}-${day}`;
              formData[fieldKey] = convertedValue;
            } else {
              // 如果正则匹配失败，尝试使用Date对象（作为备用方案）
              const date = new Date(value);
              if (!isNaN(date.getTime())) {
                const year = date.getFullYear();
                const month = String(date.getMonth() + 1).padStart(2, '0');
                const day = String(date.getDate()).padStart(2, '0');

                const convertedValue = `${year}-${month}-${day}`;
                formData[fieldKey] = convertedValue;
              } else {
                formData[fieldKey] = "";
              }
            }
          } catch (error) {
            formData[fieldKey] = "";
          }
        } else {
          formData[fieldKey] = "";
        }
      }
      // 文件上传字段特殊处理
      else if (fieldConfig.type === 'file-upload' || fieldConfig.type === 'image-upload' || fieldConfig.type === 'attachment-upload') {
        if (value && typeof value === 'string') {
          // 如果是文件ID字符串，转换为UI组件期望的数组格式
          const fileInfo = {
            name: fieldConfig.type === 'image-upload' ? "图片" : "文件",
            url: getImageUrl(value),
            extname: fieldConfig.type === 'image-upload' ? "jpg" : "pdf",
            size: 0,
            fileID: value,
            id: value, // attachment-upload 组件需要 id 字段
          };
          formData[fieldKey] = [fileInfo];
        } else if (Array.isArray(value) && value.length > 0) {
          // 如果已经是数组格式，直接使用
          formData[fieldKey] = value;
        } else {
          // 没有文件时设置为空数组
          formData[fieldKey] = [];
        }
      }
      // 普通字段
      else {
        formData[fieldKey] = value || "";
      }
    });
  };

  /**
   * 获取图片URL
   */
  const getImageUrl = (fileId: string | null): string => {
    if (!fileId) return "";
    return `${import.meta.env.VITE_BASE_URL}/api/_file/getfile/${fileId}`;
  };

  /**
   * 获取身份证照片的值用于回显
   */
  const getIdCardPhotoValue = (fieldKey: "idCardFrontPhoto" | "idCardBackPhoto") => {
    const photoId = formData[fieldKey];
    if (!photoId) return [];

    // 如果有照片ID，构造文件对象用于回显
    return [
      {
        name: fieldKey === "idCardFrontPhoto" ? "身份证正面" : "身份证反面",
        url: getImageUrl(photoId),
        extname: "jpg",
        size: 0,
        fileID: photoId,
      },
    ];
  };

  /**
   * 处理身份证照片删除
   */
  const handleIdCardPhotoDelete = (fieldKey: "idCardFrontPhoto" | "idCardBackPhoto") => {
    formData[fieldKey] = "";
    validateField(fieldKey);
  };

  /**
   * 获取图片样式配置
   */
  const getImageStyles = (config: any, fieldKey?: string) => {
    // 身份证照片使用专门的尺寸
    if (fieldKey === "idCardFrontPhoto" || fieldKey === "idCardBackPhoto") {
      return {
        width: 180,
        height: 120,
        border: { radius: "8px" },
      };
    }

    if (config?.listType === "picture-card") {
      return {
        width: 100,
        height: 100,
        border: { radius: "8px" },
      };
    }
    return {
      width: 160,
      height: 100,
      border: { radius: "8px" },
    };
  };

  /**
   * 重置表单数据
   */
  const resetFormData = () => {
    Object.keys(formData).forEach(key => {
      formData[key] = "";
    });
    Object.keys(pickerValues).forEach(key => {
      pickerValues[key] = "";
    });
    Object.keys(formErrors).forEach(key => {
      delete formErrors[key];
    });
  };

  /**
   * CRUD操作方法
   */
  const crudOperations = {
    // 创建记录
    async create(data: TViewModel): Promise<TEntity | null> {
      try {
        loading.value = true;
        const result = await apiConfig.add(data);
        return result;
      } finally {
        loading.value = false;
      }
    },

    // 更新记录
    async update(data: TViewModel): Promise<TEntity | null> {
      try {
        loading.value = true;
        const result = await apiConfig.edit(data);
        return result;
      } catch (error) {
        handleError(error, "更新失败");
        return null;
      } finally {
        loading.value = false;
      }
    },

    // 获取记录详情
    async getDetail(id: string): Promise<TEntity | null> {
      try {
        loading.value = true;
        const response = await apiConfig.get(id);
        if (response && response.Entity) {
          originalData.value = response.Entity;
          return response.Entity;
        }
        return null;
      } catch (error) {
        handleError(error, "获取详情失败");
        return null;
      } finally {
        loading.value = false;
      }
    },

    // 删除记录
    async delete(ids: string[]): Promise<boolean> {
      try {
        loading.value = true;
        await apiConfig.delete(ids);
        return true;
      } catch (error) {
        handleError(error, "删除失败");
        return false;
      } finally {
        loading.value = false;
      }
    },

    // 搜索记录
    async search(params: any): Promise<TEntity[]> {
      try {
        loading.value = true;
        const response = await apiConfig.search(params);
        return response?.Data || [];
      } catch (error) {
        handleError(error, "搜索失败");
        return [];
      } finally {
        loading.value = false;
      }
    },

    // 获取单据编号（如果支持）
    async getBillCode(): Promise<string | null> {
      if (!apiConfig.getBillCode) return null;

      try {
        const response = await apiConfig.getBillCode();
        return response?.Data || null;
      } catch (error) {
        handleError(error, "获取单据编号失败");
        return null;
      }
    }
  };

  return {
    // 响应式数据
    formData,
    pickerValues,
    formErrors,
    loading,
    originalData,

    // 基础方法
    handleError,
    validateField,
    validateAllFields,
    validateAllFieldsWithDetails,
    handlePickerChange,
    handleDateTimeChange,
    formatDateTime,
    resetFormData,

    // 文件上传相关
    handleIdCardPhotoUpload,
    getImageUrl,
    getIdCardPhotoValue,
    handleIdCardPhotoDelete,
    getImageStyles,

    // 选项数据加载
    loadOptions,
    initializeOptions,

    // API数据转换
    convertApiDataToFormData,

    // CRUD操作
    ...crudOperations,
  };
}
